package com.example.opengldemo._05_;

import android.opengl.GLES30;
import android.opengl.Matrix;
import android.util.Log;

import com.example.opengldemo.util.MatrixState;
import com.example.opengldemo.util.ShaderUtil;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;

import static android.opengl.GLES30.GL_TRIANGLES;

public class Point_Line_Shape {

    String vertexRes  = "four/vertex.sh";
    String fragmentRes  = "four/fragment.sh";

    int mProgram ;

    int m_A_PositionHandle ;
    int m_A_ColorHandle ;
    int m_U_MVPMatrixHandle ;

    FloatBuffer vertaxBuffer ;
    FloatBuffer fragBuffer ;
    ByteBuffer indexBuffer ;
    int vCount ;
    int iCount ;
    float mShape ;
    float myShape ;

    Point_Line_Shape(MySurfaceView view){
        initBufferData();
        initHandle(view) ;
        doMatrix();
    }

    private void initHandle(MySurfaceView view) {
        mProgram = ShaderUtil.createProgram(
                ShaderUtil.loadFromAssetsFile(vertexRes , view.getResources()) ,
                ShaderUtil.loadFromAssetsFile(fragmentRes , view.getResources())
                );

        m_A_PositionHandle = GLES30.glGetAttribLocation(mProgram , "aPosition");
        GLES30.glBindAttribLocation(mProgram , 1 , "aPosition");

        m_A_ColorHandle = GLES30.glGetAttribLocation(mProgram , "aColor");
        m_U_MVPMatrixHandle = GLES30.glGetUniformLocation(mProgram , "uMVPMatrix");
    }

    private void initBufferData() {
        float[] vertexArray = getVertexData();
        Log.e("vertex" , "initBufferData") ;
        for (float ff : vertexArray){
            Log.e("vertex" , ff +"") ;
        }
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertexArray.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        vertaxBuffer = byteBuffer.asFloatBuffer();
        vertaxBuffer.put(vertexArray);
        vertaxBuffer.position(0);

        float[] colorArray = getFragData();
        byteBuffer = ByteBuffer.allocateDirect(colorArray.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        fragBuffer = byteBuffer.asFloatBuffer();
        fragBuffer.put(colorArray);
        fragBuffer.position(0);

        byte[] indexArray = getIndexData() ;
        indexBuffer = ByteBuffer.allocateDirect(indexArray.length);
        indexBuffer.order(ByteOrder.nativeOrder());
        indexBuffer.put(indexArray);
        indexBuffer.position(0);


    }

    private byte[] getIndexData() {
        byte[] bytes = new byte[]{
             0 , 1 , 2 ,
             0 , 2 , 3 ,
             0 , 3 , 4 ,
             0 , 4 , 5 ,
             0 , 5 , 6 ,
             0 , 6 , 7 ,
             0 , 7 , 8 ,
             0 , 8 , 1
        };

        iCount = bytes.length ;
        return bytes;
    }

    private float[] getVertexData() {
        float UNIT_SIZE = 0.2f ;
        float z = -0.3f ;
        List<Float> flist = new ArrayList<Float>();
        flist.add(0f) ;flist.add(0f) ;flist.add(z) ;   // 0
        flist.add(-4*UNIT_SIZE) ;flist.add(4*UNIT_SIZE) ;flist.add(z) ;
        flist.add(0f) ;flist.add(2*UNIT_SIZE) ;flist.add(z) ;
        flist.add(4*UNIT_SIZE) ;flist.add(4*UNIT_SIZE) ;flist.add(z) ;
        flist.add(2*UNIT_SIZE) ;flist.add(0f) ;flist.add(z) ;
        flist.add(4*UNIT_SIZE) ;flist.add(-4*UNIT_SIZE) ;flist.add(z) ;
        flist.add(0f) ;flist.add(-2*UNIT_SIZE) ;flist.add(z) ;
        flist.add(-4*UNIT_SIZE) ;flist.add(-4*UNIT_SIZE) ;flist.add(z) ;
        flist.add(-2*UNIT_SIZE) ;flist.add(0f) ;flist.add(-0.3f) ; // 8
        vCount = flist.size() / 3;
        float[] vertexArray = new float[flist.size()]; //顶点坐标数组
        for (int i = 0; i < vCount; i++) {
            vertexArray[i * 3] = flist.get(i * 3);
            vertexArray[i * 3 + 1] = flist.get(i * 3 + 1);
            vertexArray[i * 3 + 2] = flist.get(i * 3 + 2);
        }
        return vertexArray ;
    }

    private float[] getFragData() {
        float[] colorArray = new float[vCount * 4];//顶点着色数据的初始化
        for (int i = 0; i < vCount; i++) {
            if (i % 3 == 0) { //中心点为白色，RGBA 4 个通道[1,1,1,0]
                colorArray[i * 4] = 1;
                colorArray[i * 4 + 1] = 1;
                colorArray[i * 4 + 2] = 1;
                colorArray[i * 4 + 3] = 0;
            } else { //边上的点为淡蓝色，RGBA 4 个通道[0.45,0.75,0.75,0]
                colorArray[i * 4] = 0.45f;
                colorArray[i * 4 + 1] = 0.75f;
                colorArray[i * 4 + 2] = 0.75f;
                colorArray[i * 4 + 3] = 0;
            }
        }
        return colorArray;
    }

    public void drawSelf(){
        //Log.e("Point_line" , "draw");
        GLES30.glUseProgram(mProgram);


        GLES30.glUniformMatrix4fv(m_U_MVPMatrixHandle , 1 , false , MatrixState.getFinalMatrix() , 0);
        GLES30.glVertexAttribPointer(1 , 3 , GLES30.GL_FLOAT , false , 3*4 , vertaxBuffer);
        GLES30.glVertexAttribPointer(m_A_ColorHandle , 4 , GLES30.GL_FLOAT , false , 4*4 , fragBuffer);

        GLES30.glEnableVertexAttribArray(m_A_ColorHandle);
        GLES30.glEnableVertexAttribArray(1);

        //GLES30.glDrawArrays(GLES30.GL_TRIANGLE_FAN, 0  ,vCount ); // 顶点法
        GLES30.glDrawElements(GLES30.GL_TRIANGLES,iCount,  GLES30.GL_UNSIGNED_BYTE,indexBuffer); // 索引法
        GLES30.glDisableVertexAttribArray(1);
        GLES30.glDisableVertexAttribArray(m_A_ColorHandle);

    }
    int state  = GLES30.GL_POINTS;
    public void updateDrawState(){
        switch (state){
            case GLES30.GL_POINTS :
                state = GLES30.GL_LINES ;
            case GLES30.GL_LINES :
                state = GLES30.GL_LINE_STRIP ;
            case GLES30.GL_LINE_STRIP :
                state = GLES30.GL_LINE_LOOP ;
            case GLES30.GL_LINE_LOOP :
                state = GLES30.GL_POINTS ;
        }
    }
    //GL_TRIANGLES
    //GL_TRIANGLE_STRIP
    //GL_TRIANGLE_FAN

    private void doMatrix() {
        MatrixState.setInitStack();
        MatrixState.pushMatrix();
    }

    public float[] getthreeDai(){
        final float UNIT_SIZE = 0.2f ;
        int n = 6;
        vCount=2*(n+1);
        float angdegBegin = -90;
         float angdegEnd = 90;
         float angdegSpan = (angdegEnd - angdegBegin) / n;
         float[] vertices = new float[vCount * 3]; //顶点坐标数据数组
        int count = 0;
        for (float angdeg = angdegBegin; angdeg <= angdegEnd; angdeg += angdegSpan) {
             double angrad = Math.toRadians(angdeg); //当前弧度
             vertices[count++] = ( //顶点 x 坐标
                     float) (-6f * UNIT_SIZE * Math.sin(angrad));
             vertices[count++] = ( //顶点 y 坐标
                     float) (6f * UNIT_SIZE * Math.cos(angrad));
             vertices[count++] =-1f; //顶点 z 坐标
             vertices[count++] = (float) (-UNIT_SIZE * Math.sin(angrad));

             vertices[count++] = (float) (UNIT_SIZE * Math.cos(angrad));

             vertices[count++] = -1f; //顶点 z 坐标
             }
        return vertices ;
    }

    public float[] getTreen2VertexData(){
        final float UNIT_SIZE = 0.2f ;
        int n1 = 3;
        int n2 = 5;
        vCount = 2 * (n1 + n2 + 2) + 2;
        float angdegBegin1 = 0;
        float angdegEnd1 = 90;
        float angdegSpan1 = (angdegEnd1 - angdegBegin1) / n1;
        float angdegBegin2 = 180;
        float angdegEnd2 = 270;
        float angdegSpan2 = (angdegEnd2 - angdegBegin2) / n2;
        float[] vertices = new float[vCount * 3]; //顶点坐标数据
        int count = 0;
        for (float angdeg=angdegBegin1;angdeg<=angdegEnd1;angdeg+=angdegSpan1) {
            double angrad = Math.toRadians(angdeg); //当前弧度 vertices[count++] = ( //大圆上的点
            vertices[count++] = (float) (-0.6f * UNIT_SIZE * Math.sin(angrad));//顶点坐标
            vertices[count++] = (
                    float) (0.6f * UNIT_SIZE * Math.cos(angrad));
            vertices[count++] = 0;
            vertices[count++]=(float) (-UNIT_SIZE * Math.sin(angrad));
            vertices[count++] = (float) (UNIT_SIZE * Math.cos(angrad));
            vertices[count++] = 0;
        }//小圆上的点

        vertices[count++] = vertices[count - 4];//重复第一批三角形的最后一个顶点
        vertices[count++] = vertices[count - 4];
        vertices[count++] = 0;
        for (float angdeg=angdegBegin2;angdeg<=angdegEnd2;angdeg+=angdegSpan2){
            double angrad = Math.toRadians(angdeg); //当前弧度
        if (angdeg == angdegBegin2) { //重复第二批三角形的第一个顶点
            vertices[count++] = (float) (-0.6f *UNIT_SIZE * Math .sin(angrad)); //顶点坐标
            vertices[count++] = (float) (0.6f * UNIT_SIZE * Math .cos(angrad));
            vertices[count++] = 0;
        }
        vertices[count++] = ( //大圆上的点
                float) (-0.6f * UNIT_SIZE * Math.sin(angrad));
        vertices[count++] = (float) (0.6f * UNIT_SIZE * Math .cos(angrad));
        vertices[count++] = 0;
        vertices[count++] = ( //小圆上的点
                float) (-UNIT_SIZE * Math.sin(angrad)); vertices[count++] = (float) (UNIT_SIZE * Math.cos(angrad)); vertices[count++] = 0;
    }
        return vertices ;
    }
}
